home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 51
/
Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso
/
-in_the_mag-
/
banging_the_metal
/
qdos
/
qdos4amiga2
/
romsrc
/
snd
/
snd_asm
Wrap
Text File
|
2000-01-03
|
13KB
|
634 lines
SECTION SND
INCLUDE '/INC/QDOS_inc'
INCLUDE '/INC/AMIGA_inc'
INCLUDE '/INC/AMIGQDOS_inc'
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; SND1_asm - sound routines
; - last modified 27/07/94
; These are all the necessary sound related sources, required
; to implement a QDOS BEEP on the Amiga computer.
; ...latest changes by Mark J Swift
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ROM header
BASE:
dc.l $4AFB0001 ; ROM recognition code
dc.w 0 ; add BASIC procs here
dc.w ROM_START-BASE
dc.b 0,32,'Amiga-QDOS SOUND routines v1.06',$A
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; start of ROM code
ROM_START:
movem.l d0-d3/a0-a3,-(a7)
; --------------------------------------------------------------
; allocate memory for sound variables
move.l #BV_LEN,d1
moveq #MT.ALCHP,d0
moveq #0,d2
trap #1
; --------------------------------------------------------------
; address of sound variables
move.l a0,AV.SNDV
move.l a0,a3
; --------------------------------------------------------------
; enter supervisor mode and disable interrupts
trap #0
ori.w #$0700,sr ; disable interrupts
; --------------------------------------------------------------
; link a custom routine into level 7 interrupt server
lea AV.LVL7link,a1
lea BV.LVL7link(a3),a2
move.l (a1),(a2)
move.l a2,(a1)
lea MY_LVL7(pc),a1
move.l a1,$04(a2)
; --------------------------------------------------------------
; link a custom routine into Trap #1 exception
lea AV.TRP1link,a1
lea BV.TRP1link(a3),a2
move.l (a1),(a2)
move.l a2,(a1)
lea MY_TRP1(pc),a1
move.l a1,$04(a2)
; --------------------------------------------------------------
; initialise relevant hardware
bsr INIT_HW
; -------------------------------------------------------------
; link in external interrupt to act on sound cycle complete
lea XINT_SERver(pc),a1 ; address of routine
lea BV.XINTLink(a3),a0
move.l a1,4(a0)
moveq #MT.LXINT,d0
trap #1
; --------------------------------------------------------------
; enable interrupts and re-enter user mode
andi.w #$D8FF,sr
; --------------------------------------------------------------
; initiate a sound process
movem.l d5/d7,-(a7)
lea BLIP(pc),a3
moveq #$11,d0
trap #1
movem.l (a7)+,d5/d7
; --------------------------------------------------------------
ROM_EXIT:
movem.l (a7)+,d0-d3/a0-a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; initialise sound for use.
INIT_HW:
movem.l d0-d2/a0/a3,-(a7)
; --------------------------------------------------------------
; initialise hardware
move.w #%0000000010000000,INTENA ; disable AUD0 ints
move.w #$000F,DMACONW ; kill sound
move.w #%0000000010000000,INTREQ ; clear AUD0 ints
move.l a7,d0
andi.l #$FFFF8000,d0
move.l d0,a0 ; Calc address of sys vars
move.b #0,SV_SOUND(a0) ; signal as not beeping
movem.l (a7)+,d0-d2/a0/a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; external interrupt server
XINT_SERver:
movem.l d7/a0,-(a7)
move.w INTENAR,d7 ; read interrupt enable reg
btst #7,d7 ; branch if AUD0 ints not on
beq XINT_OTHer
move.w INTREQR,d7 ; read interrupt request reg
btst #7,d7 ; branch if from AUD0
bne AUD0_SERV
; --------------------------------------------------------------
; otherwise let another external interrupt server handle it
XINT_OTHer:
movem.l (a7)+,d7/a0
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Interrupt from AUD0
AUD0_SERV:
move.l a7,d7
andi.l #$FFFF8000,d7
move.l d7,a0 ; Calc address of sys vars
tst.b SV_SOUND(a0) ; are we beeping?
beq.s XINT_OTHer ; no.
move.w #%0000000010000000,INTREQ ; clear interrupts
movem.l d1-d4/a0/a1,-(a7)
move.l AV.SNDV,a1
moveq #0,d0
move.w BV.BEEP(a1),d0 ; previous pitch
move.l d0,d2
add.w #11,d2 ; calc. length of sample
lsl.l #4,d2 ; scale it
add.l d0,d2
move.l BV.DURVAL(a1),d1
beq.s AUD0_L1 ; infinite dur.
add.l d2,BV.DURCNT(a1) ; increment dur count
move.l BV.DURCNT(a1),d3
cmp.l d3,d1
ble AUD0_DONe ; finished?
AUD0_L1:
move.w BV.NOTE(a1),d0 ; calculated pitch
move.l BV.GRDVAL(a1),d1
beq AUD0_G3 ; no sequence duration
add.l d2,BV.GRDCNT(a1) ; increment pitch count
move.l BV.GRDCNT(a1),d2
cmp.l d2,d1
bgt AUD0_G3 ; still counting...
move.w BV.PITCH(a1),d0 ; ideal pitch
AUD0_LUP:
tst.w BV.PITINC(a1)
beq AUD0_G1 ; no pitch increment
add.w BV.PITINC(a1),d0
tst.w BV.PITINC(a1)
bmi.s AUD0_P2
AUD0_P1:
move.w BV.PITCH2(a1),d3
cmp.w d0,d3 ; reached limit?
bgt.s AUD0_G1 ; no
move.w BV.REPCNT(a1),d4
dbra d4,AUD0_R1
move.w BV.REPVAL(a1),d4
move.w d4,BV.REPCNT(a1)
lsl.w #1,d3
sub.w d0,d3
move.w d3,d0
neg.w BV.PITINC(a1) ; bounce
bra.s AUD0_P2
AUD0_R1:
move.w d4,BV.REPCNT(a1)
sub.w d3,d0
add.w BV.PITCH1(a1),d0 ; repeat
bra.s AUD0_P1
AUD0_P2:
move.w BV.PITCH1(a1),d3
cmp.w d0,d3 ; reached limit?
blt.s AUD0_G1 ; no
move.w BV.REPCNT(a1),d4
dbra d4,AUD0_R2
move.w BV.REPVAL(a1),d4
move.w d4,BV.REPCNT(a1)
lsl.w #1,d3
sub.w d0,d3
move.w d3,d0
neg.w BV.PITINC(a1) ; bounce
bra.s AUD0_P1
AUD0_R2:
move.w d4,BV.REPCNT(a1)
sub.w d3,d0
add.w BV.PITCH2(a1),d0 ; repeat
bra.s AUD0_P2
AUD0_G1:
sub.l d1,d2
cmp.l d2,d1
blt.s AUD0_LUP
move.l d2,BV.GRDCNT(a1)
move.w d0,BV.PITCH(a1)
move.w BV.RAND(a1),d1
beq.s AUD0_G3
move.w BV.SEED(a1),d2
addq.w #1,d2
mulu.w #33,d2
divu #257,d2
clr.w d2
swap d2
subq.w #1,d2
andi.w #$FF,d2
move.w d2,BV.SEED(a1) ; make a random number
addq.w #1,d1
divu d1,d2
swap d2
lsr.w #1,d1
sub.w d2,d1
add.w d1,d0 ; RANDomise note
andi.w #$00FF,d0
AUD0_G3:
bsr SETBEEP ; new sound params
bra.s AUD0_EXIt
AUD0_DONe:
bsr INIT_HW
AUD0_EXIt:
movem.l (a7)+,d1-d4/a0/a1
XINT_EXIt:
bra XINT_OTHer
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SETBEEP:
move.w d0,BV.NOTE(a1)
move.w BV.FUZZ(a1),d1
beq.s SETBEEP1
move.w BV.SEED(a1),d2
addq.w #1,d2
mulu.w #33,d2
divu #257,d2
clr.w d2
swap d2
subq.w #1,d2
andi.w #$FF,d2
move.w d2,BV.SEED(a1) ; make a random number
addq.w #1,d1
divu d1,d2
swap d2
lsl.w #2,d2
add.w d2,d0
andi.w #$00FF,d0
SETBEEP1:
move.w d0,BV.BEEP(a1)
move.w d0,d1
addi.w #11,d1 ; calc. length of sample
move.w d1,d0
lsr.w #1,d0 ; calc. AUDXLEN
move.w d0,AUD0LEN
lea SAMPLE,a0
lea 140(a0),a0 ; half way thro' sample
move.l a0,d2
ext.l d0
sub.l d0,d2
bclr #0,d2 ; calc. AUDXLC
move.l d2,AUD0LC
move.w #313,d0 ; AUDXPER
bclr #0,d1 ; need to adjust AUDXPER?
beq.s SETBEEP2 ; no.
move.w d0,d2
ext.l d2
divu d1,d2
add.w d2,d0 ; calc. new AUDXPER
SETBEEP2:
move.w d0,AUD0PER
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Custom LVL7 routine to initialise hardware
MY_LVL7:
bsr INIT_HW
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.SNDV,a3
move.l BV.LVL7link(a3),a3
move.l 4(a3),4(a7) ; address of next routine
movem.l (a7)+,a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; A patch to replace TRAP#1 calls to: MT_IPCOM (d0=$10 and $11)
MY_TRP1:
bsr INI_A5A6
cmp.b #$11,d0
beq MT_IPCOM
MY_TRP1X:
movem.l (a7)+,d7/a5/a6 ; restore registers
subq.l #4,a7
movem.l a3,-(a7)
move.l AV.SNDV,a3
move.l BV.TRP1link(a3),a3
move.l 4(a3),4(a7) ; address of next routine
movem.l (a7)+,a3
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; initialise A5 and A6 prior to performing a TRAP routine
INI_A5A6
SUBQ.L #8,A7
MOVE.L 8(A7),-(A7)
MOVEM.L D7/A5/A6,4(A7)
move.l a7,d7
andi.l #$FFFF8000,d7
move.l d7,a6 ; Calc address of sys vars
LEA 4(A7),A5 ; A5 points to saved
; Registers D7,A5,A6
MOVEQ #$7F,D7
AND.L D7,D0
RTS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; TRAP #1 with D0=$11
MT_IPCOM:
cmp.b #10,(a3) ; is IPC command initiate sound ?
beq.s MT_IPC10
cmp.b #11,(a3) ; is it kill sound ?
bne MY_TRP1X ; no
MT_IPC11:
bsr INIT_HW
moveq #0,d0
bra TRAP1_X ; exit
MT_IPC10:
movem.l d1-d2/a0-a2,-(a7)
move.l AV.SNDV,a1
move.l a3,a2
cmp.b #8,1(a3)
beq.s IPC_SKP0
; --------------------------------------------------------------
; change 16 parameter sound into an 8 parameter one
lea SAMPLE,a2
move.b $6(a3),$6(a2)
move.b $8(a3),$7(a2)
move.w $A(a3),$8(a2)
move.w $C(a3),$A(a2)
move.b $E(a3),d0
lsl.b #4,d0
move.b $10(a3),d1
andi.b #$F,d1
or.b d1,d0
move.b d0,$C(a2)
move.b $12(a3),d0
lsl.b #4,d0
move.b $14(a3),d1
andi.b #$F,d1
or.b d1,d0
move.b d0,$D(a2)
; --------------------------------------------------------------
IPC_SKP0:
moveq #0,d1
move.b $6(a2),d1
sub.b #1,d1 ; get PITCH1
moveq #0,d2
move.b $7(a2),d2
sub.b #1,d2 ; get PITCH2
cmp.w d1,d2
bge.s IPC_SKP1
exg d1,d2
IPC_SKP1:
move.w d1,BV.PITCH1(a1)
move.w d2,BV.PITCH2(a1)
; --------------------------------------------------------------
move.b $9(a2),d0 ; gradient hi
lsl.w #8,d0
move.b $8(a2),d0 ; gradient lo
mulu #14,d0
move.l d0,BV.GRDVAL(a1)
; --------------------------------------------------------------
move.b $B(a2),d0 ; duration hi
lsl.w #8,d0
move.b $A(a2),d0 ; duration lo
mulu #14,d0
move.l d0,BV.DURVAL(a1)
; --------------------------------------------------------------
moveq #0,d0
move.b $C(a2),d0 ; repeats
andi.b #$0F,d0
move.w d0,BV.REPVAL(a1)
move.w d0,BV.REPCNT(a1)
; --------------------------------------------------------------
move.b $C(a2),d0 ; get pitch increment
lsr.b #4,d0
cmpi.b #8,d0
bne.s IPC_SKP5
move.w d1,d0
sub.w d2,d0 ; maximise pitch inc
bra.s IPC_SKP2
IPC_SKP5:
lsl.b #4,d0
ext.w d0
asr.w #4,d0 ; sign extend
tst.w d0
bgt.s IPC_SWP3
IPC_SKP2:
move.w d2,BV.PITCH(a1) ; current ideal value
bra.s IPC_SWP4
IPC_SWP3:
move.w d1,BV.PITCH(a1) ; current ideal value
; --------------------------------------------------------------
IPC_SWP4:
cmp.w d1,d2
bne.s IPC_SWP5
moveq #0,d0
IPC_SWP5:
move.w d0,BV.PITINC(a1)
; --------------------------------------------------------------
moveq #0,d0
move.b $D(a2),d0 ; fuzz
andi.b #$F,d0
subq.w #$7,d0 ; make 0-8
bge.s IPC_SKP3
clr.w d0
IPC_SKP3:
move.w d0,BV.FUZZ(a1)
; --------------------------------------------------------------
moveq #0,d0
move.b $D(a2),d0 ; randomness
lsr.b #4,d0
subq.w #$7,d0 ; make 0-8
bge.s IPC_SKP4
clr.w d0
IPC_SKP4:
move.w d0,BV.RAND(a1)
clr.l BV.DURCNT(a1)
clr.l BV.GRDCNT(a1)
clr.w BV.SEED(a1)
; --------------------------------------------------------------
lea SAMPLE,a0
lea BEEPBEG(pc),a2
move.w #((BEEPEND-BEEPBEG)/2-1),d0
MOVSNDLUP:
move.w (a2)+,(a0)+
dbra d0,MOVSNDLUP
; --------------------------------------------------------------
move.l a7,d0
andi.l #$FFFF8000,d0
move.l d0,a0 ; Calc address of sys vars
move.b #$FF,SV_SOUND(a0) ; signal as beeping
; --------------------------------------------------------------
move.w #64,AUD0VOL ; set volume
move.w #$FF,ADKCON ; no modulation
move.w BV.PITCH(a1),d0
bsr SETBEEP
; --------------------------------------------------------------
move.w #%0000000010000000,INTREQ ; clear interrupts
move.w #$8001,DMACONW ; start sound
move.w #%1000000010000000,INTENA ; enable interrupts
movem.l (a7)+,d1-d2/a0-a2
moveq #0,d0
bra TRAP1_X ; exit
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; exit from TRAP call
TRAP1_X movem.l (a7)+,d7/a5/a6 ; exit from exception
rte
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; BEEP sound sample, a square wave with rippled edges.
BEEPBEG:
DC.B $8D,$8B,$88,$86,$84,$83,$82,$81,$82,$83,$84,$86,$88,$8B,$8D,$8F
DC.B $90,$91,$91,$91,$90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81,$82,$83
DC.B $84,$86,$88,$8B,$8D,$8F,$90,$91,$91,$91,$90,$8F,$8D,$8B,$88,$86
DC.B $84,$83,$82,$81,$82,$83,$84,$86,$88,$8B,$8D,$8F,$90,$91,$91,$91
DC.B $90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81,$82,$83,$84,$86,$88,$8B
DC.B $8D,$8F,$90,$91,$91,$91,$90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81
DC.B $82,$83,$84,$86,$88,$8B,$8D,$8F,$90,$91,$91,$91,$90,$8F,$8D,$8B
DC.B $88,$86,$84,$83,$82,$81,$82,$83,$84,$86,$88,$8B,$8D,$8F,$90,$91
DC.B $91,$91,$90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81,$7F,$7E,$7D,$7C
DC.B $7A,$78,$75,$73,$71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78,$7A,$7C
DC.B $7D,$7E,$7F,$7E,$7D,$7C,$7A,$78,$75,$73,$71,$70,$6F,$6F,$6F,$70
DC.B $71,$73,$75,$78,$7A,$7C,$7D,$7E,$7F,$7E,$7D,$7C,$7A,$78,$75,$73
DC.B $71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78,$7A,$7C,$7D,$7E,$7F,$7E
DC.B $7D,$7C,$7A,$78,$75,$73,$71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78
DC.B $7A,$7C,$7D,$7E,$7F,$7E,$7D,$7C,$7A,$78,$75,$73,$71,$70,$6F,$6F
DC.B $6F,$70,$71,$73,$75,$78,$7A,$7C,$7D,$7E,$7F,$7E,$7D,$7C,$7A,$78
DC.B $75,$73,$71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78,$7A,$7C,$7D,$7E
DC.B $7F,$7E,$7D,$7C,$7A,$78,$75,$73
BEEPEND:
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; IPC10 BEEP sound process... a short blip
BLIP:
DC.B $0A,$08,$AA,$AA,$55,$55
DC.B $01,$01,$00,$00,$00,$04,$00,$00
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
END